package com.ethink.framework.feign;

import feign.Request;
import feign.Response;
import feign.Util;
import feign.slf4j.Slf4jLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;

import static feign.Util.UTF_8;
import static feign.Util.decodeOrDefault;

@Slf4j
public class FeignLogger extends Slf4jLogger {

    @Override
    protected void logRequest(String configKey, Level logLevel, Request request) {
        try {
            String bodyText =
                    request.charset() != null
                            ? new String(request.body(), request.charset())
                            : null;
            log(configKey, "%s", bodyText != null ? bodyText : "Binary data");
        } catch (Exception e) {
            log.error("print feign logRequest error", e);
        }
    }

    @Override
    protected Response logAndRebufferResponse(String configKey,
                                              Level logLevel,
                                              Response response,
                                              long elapsedTime) throws IOException {
        if (response.body() != null) {
            byte[] bodyData = Util.toByteArray(response.body().asInputStream());
            try {
                String bodyText = decodeOrDefault(bodyData, UTF_8, "Binary data");
                if (StringUtils.isNotBlank(bodyText) && bodyText.length() > 8000) {
                    bodyText = bodyText.substring(0, 8000) + "...";
                }
                log(configKey, "%s", bodyText);
            } catch (Exception e) {
                log.error("print feign logAndRebufferResponse error", e);
            }
            return response.toBuilder().body(bodyData).build();
        }
        return response;
    }

    @Override
    protected void log(String configKey, String format, Object... args) {
        log.info(String.format(methodTag(configKey) + format, args));
    }
}